package com.hellobike.haxing.modules.shop.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hellobike.haxing.common.annotation.AutoLog;
import com.hellobike.haxing.common.system.base.controller.BaseController;
import com.hellobike.haxing.common.system.query.QueryGenerator;
import com.hellobike.haxing.common.system.vo.LoginUser;
import com.hellobike.haxing.common.vo.Result;
import com.hellobike.haxing.modules.product.entity.City;
import com.hellobike.haxing.modules.product.entity.District;
import com.hellobike.haxing.modules.product.entity.Street;
import com.hellobike.haxing.modules.product.mapper.CityMapper;
import com.hellobike.haxing.modules.product.mapper.DistrictMapper;
import com.hellobike.haxing.modules.product.mapper.StreetMapper;
import com.hellobike.haxing.modules.shop.entity.BankAbbs;
import com.hellobike.haxing.modules.shop.entity.Shop;
import com.hellobike.haxing.modules.shop.mapper.BankAbbsMapper;
import com.hellobike.haxing.modules.shop.request.ShopAuditRequest;
import com.hellobike.haxing.modules.shop.service.IShopService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 自提点
 * @Author: haxing-boot
 * @Date: 2020-02-03
 * @Version: V1.0
 */
@RestController
@RequestMapping("/product/shop")
@Slf4j
public class ShopController extends BaseController<Shop, IShopService> {
    @Autowired
    private IShopService shopService;

    @Autowired
    private CityMapper cityMapper;

    @Autowired
    private StreetMapper streetMapper;

    @Autowired
    private DistrictMapper districtMapper;

    @Autowired
    private BankAbbsMapper bankAbbsMapper;

    /**
     * 分页列表查询
     *
     * @param shop
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "t_shop-分页列表查询")
    @GetMapping(value = "/list")

    public Result<?> queryPageList(Shop shop,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<Shop> queryWrapper = QueryGenerator.initQueryWrapper(shop, req.getParameterMap());
        queryWrapper.eq("shop_type", 1);
        Page<Shop> page = new Page<Shop>(pageNo, pageSize);
        IPage<Shop> pageList = shopService.page(page, queryWrapper.orderByDesc("id"));
        if (pageList != null) {
            Set<Long> cityIdList = new HashSet<>();
            Set<Long> districtIdList = new HashSet<>();
            Set<Long> streetIdList = new HashSet<>();
            if (!CollectionUtils.isEmpty(pageList.getRecords())) {
                for (Shop record : pageList.getRecords()) {
                    cityIdList.add(record.getCityId());
                    districtIdList.add(record.getDistrictId());
                    streetIdList.add(record.getStreetId());
                }
                List<City> cityList = cityMapper.selectList(new QueryWrapper<City>().lambda().in(City::getId, cityIdList));
                List<Street> streetList = streetMapper.selectList(new QueryWrapper<Street>().lambda()
                        .in(Street::getId, streetIdList));
                List<District> districtList = districtMapper.selectList(new QueryWrapper<District>().lambda()
                        .in(District::getId, districtIdList));
                Map<Long, City> cityMap = cityList.stream().collect(Collectors.toMap(City::getId, city -> city));
                Map<Long, District> districtMap = districtList.stream().collect(Collectors.toMap(District::getId, district -> district));
                Map<Long, Street> streetMap = streetList.stream().collect(Collectors.toMap(Street::getId, street -> street));
                for (Shop record : pageList.getRecords()) {
                    try {
                        record.setCityName(cityMap.get(record.getCityId()).getName());
                    } catch (Exception ex) {
                        log.error("", ex);
                    }
                    try {
                        record.setDistrictName(districtMap.get(record.getDistrictId()).getName());
                    } catch (Exception ex) {
                        log.error("", ex);
                    }
                    try {
                        record.setStreetName(streetMap.get(record.getStreetId()).getName());
                    } catch (Exception ex) {
                        log.error("", ex);
                    }
                }
            }

        }
        return Result.ok(pageList);
    }


    /**
     * 通过excel导入数据
     *
     * @param file
     * @return
     */
    @AutoLog(value = "批量导入团长信息", operateType = 5)
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(@RequestParam(value = "file") MultipartFile file) {
        try {
            shopService.importShop(file);
            return Result.ok("导入成功");
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("系统错误！");
        }
    }

    /**
     * 开启店铺
     */
    @AutoLog(value = "开启店铺", operateType = 11)
    @RequestMapping(value = "/open")
    public Result<?> open(@RequestParam(name = "id", required = true) Long id) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        return shopService.openShop(id, sysUser.getUsername());
    }

    /**
     * 开启店铺
     */
    @AutoLog(value = "审核店铺-失败", operateType = 11)
    @RequestMapping(value = "/audit-falid")
    public Result<?> auditFaild(@RequestBody ShopAuditRequest request) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        return shopService.audit(request.getId(), sysUser.getUsername(), 3, request.getReason(), null, null);
    }

    /**
     * 开启店铺
     */
    @AutoLog(value = "审核店铺", operateType = 11)
    @RequestMapping(value = "/audit")
    public Result<?> audit(@RequestParam(name = "id", required = true) Long id,
                           @RequestParam Integer state,
                           @RequestParam(required = false) Long leadShopId,
                           @RequestParam(required = false) String bankCode,
                           @RequestParam(required = false) String reason) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        return shopService.audit(id, sysUser.getUsername(), state, reason, leadShopId, bankCode);
    }

    /**
     * 开启店铺
     */
    @AutoLog(value = "店铺详情", operateType = 11)
    @RequestMapping(value = "/detail")
    public Result<?> detail(@RequestParam(name = "id", required = true) Long id) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        Shop shop = shopService.getById(id);
        if (shop != null) {
            City city = cityMapper.selectById(shop.getCityId());
            District district = districtMapper.selectById(shop.getDistrictId());
            Street street = streetMapper.selectById(shop.getStreetId());
            if (city != null) {
                shop.setCityName(city.getName());
            }
            if (district != null) {
                shop.setDistrictName(district.getName());
            }
            if (street != null) {
                shop.setStreetName(street.getName());
            }
            return Result.ok(shop);
        } else {
            return Result.error("店铺不存在");
        }
    }

    @PostMapping(value = "/bankAbbs")
    @AutoLog(value = "查询系统用户信息", operateType = 12)
    public Result<?> bankAbbs() {
        List<BankAbbs> bankAbbs = bankAbbsMapper.selectList(null);
        List<JSONObject> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(bankAbbs)) {
            for (BankAbbs ba : bankAbbs) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("value", ba.getBankAbbs());
                jsonObject.put("text", ba.getBankName());
                list.add(jsonObject);
            }
        }
        return Result.ok(list);
    }

    @PostMapping(value = "/leader")
    @AutoLog(value = "查询系统用户信息", operateType = 12)
    public Result<?> leader(@RequestParam Long id) {
        List<Shop> shops = shopService.list(new QueryWrapper<Shop>()
                .lambda().in(Shop::getShopType, 1, 2).eq(Shop::getState, 1).ne(Shop::getId, id));
        List<JSONObject> list = new ArrayList<>();
        JSONObject defaultJSON = new JSONObject();
        defaultJSON.put("value",0);
        defaultJSON.put("text","默认推广员");
        list.add(defaultJSON);
        if (!org.apache.shiro.util.CollectionUtils.isEmpty(shops)) {
            for (Shop shop : shops) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("value", shop.getId());
                jsonObject.put("text", shop.getRealName());
                list.add(jsonObject);
            }
        }
        return Result.ok(list);
    }

    /**
     * 开启店铺
     */
    @AutoLog(value = "关闭店铺", operateType = 11)
    @RequestMapping(value = "/close")
    public Result<?> close(@RequestParam(name = "id", required = true) Long id) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        return shopService.closeShop(id, sysUser.getUsername());
    }

    /**
     * 添加
     *
     * @param shop
     * @return
     */
    @AutoLog(value = "t_shop-添加", operateType = 2)
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody Shop shop) {
        shopService.save(shop);
        return Result.ok("添加成功！");
    }

    /**
     * 编辑
     *
     * @param shop
     * @return
     */
    @AutoLog(value = "t_shop-编辑", operateType = 3)
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody Shop shop) {
        if (shop.getLeadShopId() != null && shop.getLeadShopId() > 0) {
            Shop leader = shopService.getById(shop.getLeadShopId());
            if (leader != null) {
                shop.setLeadShopMobile(leader.getMobile());
            }
        }
        shopService.updateById(shop);
        return Result.ok("编辑成功!");
    }


    /**
     * 已开通的省份
     *
     * @return
     */
    @GetMapping("/openedProvinces")
    public Result getOpenedProvinces() {
        return Result.ok(shopService.getOpenedProvinces());
    }

    /**
     * 省下已开通的城市
     *
     * @param provinceId
     * @return
     */
    @GetMapping("/openedCitiesInProvince")
    public Result getOpenedCitiesByProvinceId(@RequestParam(name = "provinceId", required = true) Long provinceId) {
        return Result.ok(shopService.getOpenedCitiesByProvinceId(provinceId));
    }

    /**
     * 多个省下已开通的城市
     *
     * @param provinceIds
     * @return
     */
    @GetMapping("/openedCitiesInProvinces")
    public Result getOpenedCitiesByProvinceIds(@RequestParam(name = "provinceIds", required = true) String provinceIds) {
        return Result.ok(shopService.getOpenedCitiesByProvinceIds(Arrays.asList(provinceIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList())));
    }

    /**
     * 所有已开通的城市
     *
     * @return
     */
    @GetMapping("/allOpenedCities")
    public Result getAllOpenedCities() {
        return Result.ok(shopService.getAllOpenedCities());
    }

    /**
     * 城市下已开通的区县
     *
     * @param cityId
     * @return
     */
    @GetMapping("/openedDistrictsInCity")
    public Result getOpenedDistrictsByCityId(@RequestParam(name = "cityId", required = true) Long cityId) {
        return Result.ok(shopService.getOpenedDistrictsByCityId(cityId));
    }

    /**
     * 多个城市下已开通的区县
     *
     * @param cityIds
     * @return
     */
    @GetMapping("/openedDistrictsInCities")
    public Result getOpenedDistrictsByCityIds(@RequestParam(name = "cityIds", required = true) String cityIds) {
        return Result.ok(shopService.getOpenedDistrictsByCityIds(Arrays.asList(cityIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList())));
    }

    /**
     * 区县下已开通的街道
     *
     * @param districtId
     * @return
     */
    @GetMapping("/openedStreetsInDistrict")
    public Result getOpenedStreetsByDistrictId(@RequestParam(name = "districtId", required = true) Long districtId) {
        return Result.ok(shopService.getOpenedStreetsByDistrictId(districtId));
    }

    /**
     * 多个区县下已开通的街道
     *
     * @param districtIds
     * @return
     */
    @GetMapping("/openedStreetsInDistricts")
    public Result getOpenedStreetsByDistrictIds(@RequestParam(name = "districtIds", required = true) String districtIds) {
        return Result.ok(shopService.getOpenedStreetsByDistrictIds(Arrays.asList(districtIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList())));
    }

    /**
     * 街道下的自提点
     *
     * @param streetId
     * @return
     */
    @GetMapping("/shopsInStreet")
    public Result getShopsByStreetId(@RequestParam(name = "streetId", required = true) Long streetId) {
        return Result.ok(shopService.getShopsByStreetId(streetId));
    }

    /**
     * 多个街道下的自提点
     *
     * @param streetIds
     * @return
     */
    @GetMapping("/shopsInStreets")
    public Result getShopsByStreetIds(@RequestParam(name = "streetIds", required = true) String streetIds) {
        return Result.ok(shopService.getShopsByStreetIds(Arrays.asList(streetIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList())));
    }

    /**
     * 批量查询自提点
     *
     * @param shopIds
     * @return
     */
    @GetMapping("/getShopsByIds")
    public Result getShopsByIds(@RequestParam(name = "shopIds", required = true) String shopIds) {
        return Result.ok(shopService.listByIds(Arrays.asList(shopIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList())));
    }
}
